﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Da = VLUNewsData;
using DaMo = VLUNewsData.EntityDataModel;
using BuUt = VLUNewsBusiness.Utilities;
using System.Collections;
using System.Data.Objects;

namespace VLUNewsBusiness.VLUSitemap
{
    public class Sitemap
    {
        #region Base members
        private static Sitemap _Instance = null;
        public static Sitemap Instance()
        {
            if (_Instance == null) _Instance = new Sitemap();
            return _Instance;
        }

        public static void Release()
        {
            if (_Instance != null)
                GC.SuppressFinalize(_Instance);
        }
        #endregion Base members

        public int Save(int pSitemapID, int pPortalID, int? pParentID, string pSitemapName, string pURL, bool pIsSecurity, int pSortOrder, int pUserID)
        {
            int result = -1;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                var model = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pSitemapID).FirstOrDefault();
                if (model == null)
                {
                    model = new DaMo.VluNewsSitemap();
                    model.CreatedByUserID = pUserID;
                    model.CreatedOnDate = DateTime.Now;
                    ent.VluNewsSitemaps.AddObject(model);
                }
                model.PortalID = pPortalID;
                model.ParentID = pParentID == -1 ? null : pParentID;
                //if (pParentID > -1)
                //{
                //    DaMo.VluNewsSitemap parent = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pParentID).FirstOrDefault();
                //    model.VluNewsSitemap2 = parent; ;
                //}
                model.SitemapName = pSitemapName;
                model.URL = pURL;
                model.IsSecurity = pIsSecurity;
                model.SortOrder = pSortOrder;

                model.LastModifiedByUserID = pUserID;
                model.LastModifiedOnDate = DateTime.Now;

                result = ent.SaveChanges();
                // Update SortOrder
                var query = ent.VluNewsSitemaps.Where(p => p.ParentID == pParentID && p.SiteMapID != pSitemapID).OrderBy(p => p.SortOrder).Skip(pSortOrder - 1);
                foreach (var item in query)
                {
                    item.SortOrder += 1;
                }
                ent.SaveChanges();
            }// using.
            return result;
        }
        public int UpdateSortOrder(int pSitemapID, int pSortOrder, int pUserID)
        {
            int result = -1;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                result = ent.ExecuteStoreCommand(BuUt.SqlString.updateSitemapOrder, pSitemapID, pSortOrder, pUserID, DateTime.Now);
            }
            return result;
        }

        /// <summary>
        /// * Delete Sitemap with none children.
        /// </summary>
        /// <param name="pSitemapID"></param>
        /// <returns>-1: Error; 0: Not exist; 1: Succes; 2: Have children.</returns>
        public int Delete(int pSitemapID)
        {
            int result = -1;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                var model = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pSitemapID).FirstOrDefault();
                if (model == null)
                    return 0;
                if (model.VluNewsSitemap1.Count > 0)
                {
                    return 2;
                }

                ent.VluNewsSitemaps.DeleteObject(model);
                result = ent.SaveChanges();
            }// using.
            return result;
        }

        #region Get
        public string GetSitemapName(int pSitemapID)
        {
            string result = string.Empty;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                result = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pSitemapID).Select(p => p.SitemapName).FirstOrDefault();
                if (result == null)
                    return "";
            }
            return result;
        }
        /// <summary>
        /// * Get sitemap by id.
        /// </summary>
        /// <param name="pSitemapID"></param>
        /// <returns></returns>
        public Array GetBySitemapID(int pSitemapID)
        {
            Array result = null;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                var model = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pSitemapID).FirstOrDefault();
                if (model != null)
                {
                    result = new object[] {
                        model.SiteMapID, 
                        model.ParentID,
                        model.SitemapName,
                        model.URL,
                        model.IsSecurity,
                        model.SortOrder
                    };
                }
            }
            return result;
        }
        /// <summary>
        /// * Gets all children of parent sitemap.
        /// </summary>
        /// <param name="pParentID">null: getting all chidren which are not any parent.</param>
        /// <returns></returns>
        public IList GetsChildren(int pParentID = -1)
        {
            IList result = null;
            IQueryable<DaMo.VluNewsSitemap> query;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                VluNewsSitemapCompare cmp = new VluNewsSitemapCompare();
                if (pParentID == -1)
                    query = ent.VluNewsSitemaps.Where(p => !p.ParentID.HasValue).OrderBy(p => p.SortOrder);
                    //query = ent.VluNewsSitemaps;
                else
                    query = ent.VluNewsSitemaps.Where(p => p.ParentID == pParentID).OrderBy(p => p.SortOrder);
                result = query.ToList();
                //(( List<DaMo.VluNewsSitemap>)result).Sort(cmp);
                result = query.Select(p =>
                new
                {
                    p.SiteMapID,
                    p.SitemapName,
                    p.URL,
                    p.IsSecurity,
                    p.SortOrder
                }).ToList();
#if (DEBUG)
                System.Diagnostics.Debug.WriteLine(((System.Data.Objects.ObjectQuery)query).ToTraceString());
#endif
            }
            return result;
        }
        /// <summary>
        /// * Gets all children of parent sitemap but exclude sitemap.
        /// </summary>
        /// <param name="pParentID">null: getting all chidren which are not any parent.</param>
        /// <returns></returns>
        public IList GetsChildrenExcept(int pSitemapID, int pParentID = -1)
        {
            IList result = null;
            IQueryable<DaMo.VluNewsSitemap> query;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                if (pParentID == -1)
                    query = ent.VluNewsSitemaps.Where(p => !p.ParentID.HasValue && p.SiteMapID != pSitemapID).OrderBy(p => p.SortOrder);
                else
                    query = ent.VluNewsSitemaps.Where(p => p.ParentID == pParentID && p.SiteMapID != pSitemapID).OrderBy(p => p.SortOrder);

                result = query.Select(p =>
                new
                {
                    p.SiteMapID,
                    p.SitemapName,
                    p.URL,
                    p.IsSecurity,
                    p.SortOrder
                }).ToList();
#if (DEBUG)
                System.Diagnostics.Debug.WriteLine(((System.Data.Objects.ObjectQuery)query).ToTraceString());
#endif
            }
            return result;
        }
        /// <summary>
        /// * Gets all children of parent sitemap.
        /// </summary>
        /// <param name="pParentID">null: getting all chidren which are not any parent.</param>
        /// <returns></returns>
        public IList GetsParent(int pSitemapID)
        {
            IList result = null;
            DaMo.VluNewsSitemap sm;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                sm = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pSitemapID).FirstOrDefault();
                result = new List<object>();
                while (sm.VluNewsSitemap2 != null)
                {
                    result.Insert(0, new { Key = sm.VluNewsSitemap2.SiteMapID, Value = sm.VluNewsSitemap2.SitemapName });
                    sm = sm.VluNewsSitemap2;
                }
            }
            return result;
        }// GetsParent
        /// <summary>
        /// * Gets all children of parent sitemap.
        /// </summary>
        /// <param name="pParentID">null: getting all chidren which are not any parent.</param>
        /// <returns></returns>
        public IList GetsParentByParentID(int pParentID)
        {
            if (pParentID == -1)
                return null;
            IList result = new List<object>();
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                DaMo.VluNewsSitemap sm = ent.VluNewsSitemaps.Where(p => p.SiteMapID == pParentID).FirstOrDefault();
                while (sm != null)
                {
                    result.Insert(0, new { Key = sm.SiteMapID, Value = sm.SitemapName });
                    sm = sm.VluNewsSitemap2;
                }
            }
            return result;
        }// GetsParent
        /// <summary>
        /// * Get children count of parent sitemap.
        /// </summary>
        /// <param name="pParentID">null: getting all chidren which are not any parent.</param>
        /// <returns></returns>
        public int GetChildrenCount(int pParentID = -1)
        {
            int result = 0;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                if (pParentID == -1)
                    result = ent.VluNewsSitemaps.Where(p => !p.ParentID.HasValue).Count();
                else
                    result = ent.VluNewsSitemaps.Where(p => p.ParentID == pParentID).Count();
            }
            return result;
        }

        public bool GetIsSecurity(int pSitemapID)
        {
            bool result = true;
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                result = ent.VluNewsSitemaps.Any(p => p.SiteMapID == pSitemapID && p.IsSecurity);
            }
            return result;
        }

        /// <summary>
        /// * Get all sitemap.
        /// </summary>
        /// <param name="pParentID">null: getting all chidren which are not any parent.</param>
        /// <returns></returns>
        public IList GetsAllShowList()
        {
            List<KeyValuePair<int, string>> result = new List<KeyValuePair<int, string>>();
            using (DaMo.VLUNewsEntities ent = new DaMo.VLUNewsEntities())
            {
                List<DaMo.VluNewsSitemap> query = ent.VluNewsSitemaps.ToList();
                addChildren(query, result, -1, 0);
            }
            return result;
        }

        void addChildren(List<DaMo.VluNewsSitemap> pListSitemaps, List<KeyValuePair<int, string>> pListParent, int pSitemapID, int pLevel)
        {
            string sDot = string.Empty;
            for (int i = 0; i < pLevel; i++)
            {
                sDot += "...";
            }
            List<DaMo.VluNewsSitemap> lstChildren;
            if (pSitemapID == -1)
                lstChildren = pListSitemaps.Where(p => !p.ParentID.HasValue || p.ParentID == pSitemapID).OrderBy(p => p.SortOrder).ToList();
            else
                lstChildren = pListSitemaps.Where(p => p.ParentID == pSitemapID).OrderBy(p => p.SortOrder).ToList();
            foreach (var item in lstChildren)
            {
                pListParent.Add(new KeyValuePair<int, string>(item.SiteMapID, sDot + item.SitemapName));
                addChildren(pListSitemaps, pListParent, item.SiteMapID, pLevel + 1);
            }
        }
        #endregion Get
    }

    public class VluNewsSitemapCompare : IComparer<DaMo.VluNewsSitemap>
    {
        public int Compare(DaMo.VluNewsSitemap left, DaMo.VluNewsSitemap right)
        {
            if (left.ParentID.HasValue || left.ParentID == right.SiteMapID)
                return 1;
            return 0;
        }
    }

}
